;/*
; * Copyright (c) 2022, IMMORTA Inc.
; * All rights reserved.
; *
; * Redistribution and use in source and binary forms, with or without modification,
; * are permitted provided that the following conditions are met:
; *
; * - Redistributions of source code must retain the above copyright notice, this list
; *   of conditions and the following disclaimer.
; *
; * - Redistributions in binary form must reproduce the above copyright notice, this
; *   list of conditions and the following disclaimer in the documentation and/or
; *   other materials provided with the distribution.
; *
; * - Neither the name of IMMORTA Inc. nor the names of its
; *   contributors may be used to endorse or promote products derived from this
; *   software without specific prior written permission.
; *
; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
; * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
; * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
; * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
; */

                PRESERVE8
                THUMB

;Vector Table Mapped to Address 0 at Reset
        AREA    |.text|, CODE, READONLY

        IMPORT  |Image$$ARM_LIB_STACK$$ZI$$Limit|
        IMPORT  |Image$$RW_IRAM1$$Base|
        EXPORT  __RAM_START
        EXPORT  __RAM_END

__RAM_START DCD |Image$$RW_IRAM1$$Base|
__RAM_END   DCD |Image$$ARM_LIB_STACK$$ZI$$Limit|

        AREA    RESET, DATA, READONLY
        EXPORT  __Vectors
        EXPORT  __Vectors_End
        EXPORT  __Vectors_Size

__Vectors       DCD     |Image$$ARM_LIB_STACK$$ZI$$Limit|  ;Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

                ; External Interrupts
                DCD     WDG_IRQHandler             ; Internal Watch Dog
                DCD     ERM_Error_IRQHandler       ; ERM Error
                DCD     LVD_IRQHandler             ; Low Voltage Detection
                DCD     CLOCK_Fault_IRQHandler     ; Clock Fault
                DCD     DMA_Channel0_IRQHandler    ; DMA Channel 0
                DCD     DMA_Channel1_IRQHandler    ; DMA Channel 1
                DCD     DMA_Channel2_IRQHandler    ; DMA Channel 2
                DCD     DMA_Channel3_IRQHandler    ; DMA Channel 3
                DCD     DMA_Channel4_IRQHandler    ; DMA Channel 4
                DCD     DMA_Channel5_IRQHandler    ; DMA Channel 5
                DCD     DMA_Channel6_IRQHandler    ; DMA Channel 6
                DCD     DMA_Channel7_IRQHandler    ; DMA Channel 7
                DCD     Reserved0_IRQHandler       ; Reserved0
                DCD     Reserved1_IRQHandler       ; Reserved1
                DCD     Reserved2_IRQHandler       ; Reserved2
                DCD     Reserved3_IRQHandler       ; Reserved3
                DCD     GPIOA_IRQHandler           ; GPIOA
                DCD     GPIOB_IRQHandler           ; GPIOB
                DCD     GPIOC_IRQHandler           ; GPIOC
                DCD     GPIOD_IRQHandler           ; GPIOD
                DCD     GPIOE_IRQHandler           ; GPIOE
                DCD     Reserved4_IRQHandler       ; Reserved4
                DCD     RTC_IRQHandler             ; RTC
                DCD     TIMER0_IRQHandler          ; Timer 0
                DCD     TIMER1_IRQHandler          ; Timer 1
                DCD     TIMER2_IRQHandler          ; Timer 2
                DCD     TIMER3_IRQHandler          ; Timer 3
                DCD     SPI0_IRQHandler            ; SPI 0
                DCD     SPI1_IRQHandler            ; SPI 1
                DCD     SPI2_IRQHandler            ; SPI 2
                DCD     SPI3_IRQHandler            ; SPI 3
                DCD     I2C0_IRQHandler            ; I2C 0
                DCD     I2C1_IRQHandler            ; I2C 1
                DCD     UART0_IRQHandler           ; UART 0
                DCD     UART1_IRQHandler           ; UART 1
                DCD     UART2_IRQHandler           ; UART 2
                DCD     UART3_IRQHandler           ; UART 3
                DCD     Reserved5_IRQHandler       ; Reserved5
                DCD     Reserved6_IRQHandler       ; Reserved6
                DCD     CAN0_IRQHandler            ; CAN 0
                DCD     CAN1_IRQHandler            ; CAN 1
                DCD     CAN2_IRQHandler            ; CAN 2
                DCD     Reserved7_IRQHandler       ; Reserved7
                DCD     Reserved8_IRQHandler       ; Reserved8
                DCD     Reserved9_IRQHandler       ; Reserved9
                DCD     ADC0_IRQHandler            ; ADC 0
                DCD     ADC1_IRQHandler            ; ADC 1
                DCD     CMP0_IRQHandler            ; CMP 0
                DCD     IPWM0_Channel_IRQHandler   ; IPMW 0 Channel
                DCD     IPWM0_Overflow_IRQHandler  ; IPMW 0 Overflow
                DCD     IPWM1_Channel_IRQHandler   ; IPMW 1 Channel
                DCD     IPWM1_Overflow_IRQHandler  ; IPMW 1 Overflow
                DCD     SPWM0_Channel_IRQHandler   ; SPMW 0 Channel
                DCD     SPWM0_Fault_IRQHandler     ; SPMW 0 Fault
                DCD     SPWM0_Overflow_IRQHandler  ; SPMW 0 Overflow
                DCD     SPWM1_Channel_IRQHandler   ; SPMW 1 Channel
                DCD     SPWM1_Fault_IRQHandler     ; SPMW 1 Fault
                DCD     SPWM1_Overflow_IRQHandler  ; SPMW 1 Overflow
                DCD     SPWM2_Channel_IRQHandler   ; SPMW 2 Channel
                DCD     SPWM2_Fault_IRQHandler     ; SPMW 2 Fault
                DCD     SPWM2_Overflow_IRQHandler  ; SPMW 2 Overflow
                DCD     Reserved10_IRQHandler      ; Reserved10
                DCD     MBOX_IRQHandler            ; HSM Mbox
                DCD     HSM_Error_IRQHandler       ; HSM Error

__Vectors_End

__BootHeader
                DCD   0x5AA55AA5;         ;/* Valid boot header marker */
                DCD   0x00000000;         ;/* Boot configuration word */
                                          ;/* bit0: soc wdg enable,0-disable,1-enable */
                                          ;/* bit1~bit31: reserved */
                DCD   0x00000000;         ;/* 0:HSI 1:HSE+PLL 2:HSI+PLL */
                DCD   8000000;            ;/* Frequency of EXTAL/XTAL */
                DCD   0;                  ;/* PLL previous divider, 0~63 */
                DCD   115;                ;/* PLL feedback divider, 0~4095 */
                DCD   2;                  ;/* PLL post divider1, 0~7 */
                DCD   1;                  ;/* PLL post divider2, 0~3 */
                DCD   0;                  ;/* PLL vcodiv enable, 0~1 */
                DCD   0x18000000;         ;/* HSM FW image address */
__BootHeader_End

__Vectors_Size  EQU  __Vectors_End - __Vectors

                AREA    |.text|, CODE, READONLY

; Reset handler
Reset_Handler   PROC
                EXPORT  Reset_Handler               [WEAK]
                IMPORT  __main
                IMPORT  SystemInit

                CPSID   I    ;Mask interrupts

                LDR R1, = 0x4001002C
                LDR R0, = 0x5A1234A5
                STR R0, [R1]

                LDR R1, = 0x40010020
                LDR R0, = 0xFFFFFFFF
                STR R0, [R1]

                LDR R1, = 0x40010024
                LDR R0, = 0xFFFFFFFF
                STR R0, [R1]

                LDR R1, = 0x40000000
                LDR R0, = 0x34C
                STR R0, [R1]

                ;Errata
                LDR R1, = 0x4000E800
                LDR R0, = 0x00000709
                STR R0, [R1]

                LDR R1, = 0x4000E804
                LDR R0, = 0x00000709
                STR R0, [R1]

                LDR R1, = 0x4000E414
                LDR R0, = 0x00000709
                STR R0, [R1]

                LDR R1, = 0x4000E02C
                LDR R0, = 0x0000070A
                STR R0, [R1]

                LDR R1, = 0x4000E010
                LDR R0, = 0x00000709
                STR R0, [R1]

                LDR R1, = 0x4000E410
                LDR R0, = 0x0000070A
                STR R0, [R1]

                LDR R1, = 0x4000000C
                LDR R0, = 0xB2063001
                STR R0, [R1]

                LDR R1, = 0x40002034
                LDR R0, = 0xE0402008
                STR R0, [R1]

                LDR R1, = 0x4000000C
                LDR R0, = 0xB2063000
                STR R0, [R1]

                ;Init ECC RAM
                LDR     R1, = __RAM_START
                LDR     R1, [R1]
                LDR     R2, = __RAM_END
                LDR     R2, [R2]
                SUBS    R2, R1
                SUBS    R2, #1
                BLE LE0

                MOVS    R0, #0
                MOVS    R3, #4
LE1
                STR R0, [R1]
                ADD R1, R1, R3
                SUBS R2, #4
                BGE LE1
LE0
                NOP

                LDR     R0, =SystemInit
                BLX     R0
                CPSIE   i               ;Unmask interrupts
                LDR     R0, =__main
                BX      R0
                ENDP

; Dummy Exception Handlers (infinite loops which can be modified)

NMI_Handler     PROC
                EXPORT  NMI_Handler                [WEAK]
                B       .
                ENDP
HardFault_Handler\
                PROC
                EXPORT  HardFault_Handler          [WEAK]
                B       .
                ENDP
MemManage_Handler\
                PROC
                EXPORT  MemManage_Handler          [WEAK]
                B       .
                ENDP
BusFault_Handler\
                PROC
                EXPORT  BusFault_Handler           [WEAK]
                B       .
                ENDP
UsageFault_Handler\
                PROC
                EXPORT  UsageFault_Handler         [WEAK]
                B       .
                ENDP
SVC_Handler     PROC
                EXPORT  SVC_Handler                [WEAK]
                B       .
                ENDP
DebugMon_Handler\
                PROC
                EXPORT  DebugMon_Handler           [WEAK]
                B       .
                ENDP
PendSV_Handler  PROC
                EXPORT  PendSV_Handler             [WEAK]
                B       .
                ENDP
SysTick_Handler PROC
                EXPORT  SysTick_Handler            [WEAK]
                B       .
                ENDP

Default_Handler PROC
                EXPORT  WDG_IRQHandler               [WEAK]
                EXPORT  ERM_Error_IRQHandler         [WEAK]
                EXPORT  LVD_IRQHandler               [WEAK]
                EXPORT  CLOCK_Fault_IRQHandler       [WEAK]
                EXPORT  DMA_Channel0_IRQHandler      [WEAK]
                EXPORT  DMA_Channel1_IRQHandler      [WEAK]
                EXPORT  DMA_Channel2_IRQHandler      [WEAK]
                EXPORT  DMA_Channel3_IRQHandler      [WEAK]
                EXPORT  DMA_Channel4_IRQHandler      [WEAK]
                EXPORT  DMA_Channel5_IRQHandler      [WEAK]
                EXPORT  DMA_Channel6_IRQHandler      [WEAK]
                EXPORT  DMA_Channel7_IRQHandler      [WEAK]
                EXPORT  Reserved0_IRQHandler         [WEAK]
                EXPORT  Reserved1_IRQHandler         [WEAK]
                EXPORT  Reserved2_IRQHandler         [WEAK]
                EXPORT  Reserved3_IRQHandler         [WEAK]
                EXPORT  GPIOA_IRQHandler             [WEAK]
                EXPORT  GPIOB_IRQHandler             [WEAK]
                EXPORT  GPIOC_IRQHandler             [WEAK]
                EXPORT  GPIOD_IRQHandler             [WEAK]
                EXPORT  GPIOE_IRQHandler             [WEAK]
                EXPORT  Reserved4_IRQHandler         [WEAK]
                EXPORT  RTC_IRQHandler               [WEAK]
                EXPORT  TIMER0_IRQHandler            [WEAK]
                EXPORT  TIMER1_IRQHandler            [WEAK]
                EXPORT  TIMER2_IRQHandler            [WEAK]
                EXPORT  TIMER3_IRQHandler            [WEAK]
                EXPORT  SPI0_IRQHandler              [WEAK]
                EXPORT  SPI1_IRQHandler              [WEAK]
                EXPORT  SPI2_IRQHandler              [WEAK]
                EXPORT  SPI3_IRQHandler              [WEAK]
                EXPORT  I2C0_IRQHandler              [WEAK]
                EXPORT  I2C1_IRQHandler              [WEAK]
                EXPORT  UART0_IRQHandler             [WEAK]
                EXPORT  UART1_IRQHandler             [WEAK]
                EXPORT  UART2_IRQHandler             [WEAK]
                EXPORT  UART3_IRQHandler             [WEAK]
                EXPORT  Reserved5_IRQHandler         [WEAK]
                EXPORT  Reserved6_IRQHandler         [WEAK]
                EXPORT  CAN0_IRQHandler              [WEAK]
                EXPORT  CAN1_IRQHandler              [WEAK]
                EXPORT  CAN2_IRQHandler              [WEAK]
                EXPORT  Reserved7_IRQHandler         [WEAK]
                EXPORT  Reserved8_IRQHandler         [WEAK]
                EXPORT  Reserved9_IRQHandler         [WEAK]
                EXPORT  ADC0_IRQHandler              [WEAK]
                EXPORT  ADC1_IRQHandler              [WEAK]
                EXPORT  CMP0_IRQHandler              [WEAK]
                EXPORT  IPWM0_Channel_IRQHandler     [WEAK]
                EXPORT  IPWM0_Overflow_IRQHandler    [WEAK]
                EXPORT  IPWM1_Channel_IRQHandler     [WEAK]
                EXPORT  IPWM1_Overflow_IRQHandler    [WEAK]
                EXPORT  SPWM0_Channel_IRQHandler     [WEAK]
                EXPORT  SPWM0_Fault_IRQHandler       [WEAK]
                EXPORT  SPWM0_Overflow_IRQHandler    [WEAK]
                EXPORT  SPWM1_Channel_IRQHandler     [WEAK]
                EXPORT  SPWM1_Fault_IRQHandler       [WEAK]
                EXPORT  SPWM1_Overflow_IRQHandler    [WEAK]
                EXPORT  SPWM2_Channel_IRQHandler     [WEAK]
                EXPORT  SPWM2_Fault_IRQHandler       [WEAK]
                EXPORT  SPWM2_Overflow_IRQHandler    [WEAK]
                EXPORT  Reserved10_IRQHandler        [WEAK]
                EXPORT  MBOX_IRQHandler              [WEAK]
                EXPORT  HSM_Error_IRQHandler         [WEAK]

WDG_IRQHandler
ERM_Error_IRQHandler
LVD_IRQHandler
CLOCK_Fault_IRQHandler
DMA_Channel0_IRQHandler
DMA_Channel1_IRQHandler
DMA_Channel2_IRQHandler
DMA_Channel3_IRQHandler
DMA_Channel4_IRQHandler
DMA_Channel5_IRQHandler
DMA_Channel6_IRQHandler
DMA_Channel7_IRQHandler
Reserved0_IRQHandler
Reserved1_IRQHandler
Reserved2_IRQHandler
Reserved3_IRQHandler
GPIOA_IRQHandler
GPIOB_IRQHandler
GPIOC_IRQHandler
GPIOD_IRQHandler
GPIOE_IRQHandler
Reserved4_IRQHandler
RTC_IRQHandler
TIMER0_IRQHandler
TIMER1_IRQHandler
TIMER2_IRQHandler
TIMER3_IRQHandler
SPI0_IRQHandler
SPI1_IRQHandler
SPI2_IRQHandler
SPI3_IRQHandler
I2C0_IRQHandler
I2C1_IRQHandler
UART0_IRQHandler
UART1_IRQHandler
UART2_IRQHandler
UART3_IRQHandler
Reserved5_IRQHandler
Reserved6_IRQHandler
CAN0_IRQHandler
CAN1_IRQHandler
CAN2_IRQHandler
Reserved7_IRQHandler
Reserved8_IRQHandler
Reserved9_IRQHandler
ADC0_IRQHandler
ADC1_IRQHandler
CMP0_IRQHandler
IPWM0_Channel_IRQHandler
IPWM0_Overflow_IRQHandler
IPWM1_Channel_IRQHandler
IPWM1_Overflow_IRQHandler
SPWM0_Channel_IRQHandler
SPWM0_Fault_IRQHandler
SPWM0_Overflow_IRQHandler
SPWM1_Channel_IRQHandler
SPWM1_Fault_IRQHandler
SPWM1_Overflow_IRQHandler
SPWM2_Channel_IRQHandler
SPWM2_Fault_IRQHandler
SPWM2_Overflow_IRQHandler
Reserved10_IRQHandler
MBOX_IRQHandler
HSM_Error_IRQHandler

    B       .

    ENDP

    ALIGN
    END

/*******EOF********************************************************************/